Skip to content

Fix viewer crash in unsupported GPU contexts#403

Merged
Aymericr merged 1 commit into
mainfrom
fix/sentry-EDITOR-59
Jun 24, 2026
Merged

Fix viewer crash in unsupported GPU contexts#403
Aymericr merged 1 commit into
mainfrom
fix/sentry-EDITOR-59

Conversation

@anton-pascal

@anton-pascal anton-pascal commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary\n- detect browsers/environments with neither WebGPU nor WebGL before mounting the R3F Canvas\n- render a small unsupported 3D viewer fallback instead of initializing Three's WebGPU renderer\n- switch to the same fallback when renderer init still rejects, avoiding repeated failed mounts\n\n## Validation\n- bun run --filter @pascal-app/viewer build\n- bunx biome lint packages/viewer/src/components/viewer/index.tsx\n\nFixes Sentry MONOREPO-EDITOR-59.


Note

Low Risk
Localized viewer mount/error-handling and UX fallback; no auth, data, or core business-logic changes.

Overview
Prevents crashes in environments without usable GPU rendering by not mounting the R3F Canvas / WebGPU renderer when neither WebGPU nor WebGL is available, and by showing a small “3D viewer unavailable” message instead.

After mount, capability checks run with an optimistic initial state to avoid SSR hydration mismatches. If WebGPURenderer init() still fails, the same fallback is shown via rendererInitFailed instead of leaving the canvas in a broken retry loop.

When the fallback is active, onSceneReadyChange(true) is fired so the host editor can dismiss its loader even though SceneReadyTracker never mounts.

Reviewed by Cursor Bugbot for commit 74fed4b. Bugbot is set up for automated code reviews on this repo. Configure here.

@mintlify

mintlify Bot commented Jun 14, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
pascal 🔴 Failed Jun 14, 2026, 4:08 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@anton-pascal

Copy link
Copy Markdown
Contributor Author

Nightly Sentry triage (06-16): EDITOR-59 (getSupportedExtensions of null in three.webgpu WebGLBackend.init) still unresolved, last seen 06-16 02:21 on HeadlessChrome/no-GPU clients. Related family: EDITOR-3P Cannot read properties of null (reading 'addEventListener') in @react-three/fiber events connect (last seen 06-16 01:35, Windows prod) — same root cause (missing/torn-down GL context / canvas). Please confirm this PR's guard also covers the R3F connect() null-domElement path, or it may need a companion guard.

@anton-pascal

Copy link
Copy Markdown
Contributor Author

Nightly Sentry triage 2026-06-17: EDITOR-59 (getSupportedExtensions on null GL context) is still recurring — latest event 2026-06-17T03:01Z on Mobile Safari iOS 18.7 at editor.pascal.app. Sibling issue EDITOR-AY ("Error creating WebGL context") is the same root cause (null/failed context on device). This PR's unsupported-GPU-context guard should resolve both; bumping for review. No duplicate PR opened.

@anton-pascal

Copy link
Copy Markdown
Contributor Author

Nightly Sentry triage 2026-06-18: EDITOR-59 (Cannot read properties of null (reading 'getSupportedExtensions') in three.webgpu WebGLBackend.init) still recurring — latest event 2026-06-18T03:37Z on Chrome Mobile WebView 57 (ancient in-app browser, no WebGL2/WebGPU). This PR's unsupported-GPU guard still looks like the right fix; please review/land when you can. Also seeing the sibling EDITOR-79 (isShaderMaterial on undefined) on the same old-WebView class of devices — the same context-null guard may cover it.

Adds a capability check and an UnsupportedGpuViewerFallback so the viewer
renders an informative panel instead of crashing on environments that expose
neither WebGPU nor WebGL. Capability detection runs post-mount to stay
hydration-safe, the renderer-init failure path swaps to the fallback, and the
fallback signals scene-readiness so the host editor loader does not hang.

Reworked from #403 (anton-pascal) onto current main; resolves the import
conflict and the SSR/scene-ready gotchas surfaced in review.

Co-authored-by: anton-pascal <[email protected]>
@Aymericr Aymericr force-pushed the fix/sentry-EDITOR-59 branch from 61cba2c to 74fed4b Compare June 24, 2026 19:51
@Aymericr

Copy link
Copy Markdown
Contributor

Reworked onto current main (the original diff conflicted after #438). Kept your approach but hardened it from a dual review pass:

  • Hydration safety: capability detection now runs in a post-mount effect (starts optimistic) instead of useMemo, so SSR markup and the first client render agree — avoids a fallback↔Canvas hydration mismatch.
  • Loader hang: when the fallback renders, SceneReadyTracker never mounts, so the host editor would otherwise wait on its scene-readiness timeout. The fallback now signals onSceneReadyChange(true) so the editor loader drops immediately.
  • Resolved the useLayoutEffect import conflict with main.

Typecheck + viewer tests pass. Verifying CI before merge.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 74fed4b. Configure here.

// readiness explicitly so the host can drop its loader immediately.
useEffect(() => {
if (showGpuFallback) onSceneReadyChange?.(true)
}, [showGpuFallback, onSceneReadyChange])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fallback omits scene reload signal

Medium Severity

The GPU fallback's useEffect signals scene readiness only on initial dependency changes. When the editor loads a new scene, it resets readiness, but the fallback's useEffect won't re-trigger to signal readiness again. This happens because the SceneReadyTracker isn't mounted in the fallback path, causing the editor to wait for its eight-second timeout.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 74fed4b. Configure here.

@Aymericr Aymericr merged commit 5fe0965 into main Jun 24, 2026
2 checks passed
@Aymericr Aymericr deleted the fix/sentry-EDITOR-59 branch June 24, 2026 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants